package dao.base;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

import javax.annotation.Resource;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

import com.util.PageBean;

public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {
	
	@Resource
	public void setSf(SessionFactory sessionFactory){
		super.setSessionFactory(sessionFactory);

	}
	
	private Class<T> entityClass;	//定义实体类型
	//通过构造获得实体类型
	public BaseDaoImpl() {
		ParameterizedType genericSuperclass =(ParameterizedType) this.getClass().getGenericSuperclass();//先获得父类类型
		Type[] actualTypeArguments = genericSuperclass.getActualTypeArguments();//再获得父类上的泛型参数数组
		entityClass = (Class<T>) actualTypeArguments[0];//最后获得实体类型
	}
	@Override
	public void save(T entity) {
		this.getHibernateTemplate().saveOrUpdate(entity);
		
	}

	@Override
	public void delete(T entity) {
		this.getHibernateTemplate().delete(entity);
		
	}

	@Override
	public void update(T entity) {
		this.getHibernateTemplate().update(entity);
		
	}

	@Override
	public T findById(Serializable id) {
		
		return this.getHibernateTemplate().get(entityClass, id);
	}

	@Override
	public List<T> findAll() {
		
		return (List<T>) this.getHibernateTemplate().find("from " + entityClass.getSimpleName());
	}

	@Override
	public List<T> findByCriteria(DetachedCriteria criteria) {
		
		return (List<T>) this.getHibernateTemplate().findByCriteria(criteria);
	}

	@Override
	public List<T> findByNamedQuery(String queryName, Object... args) {
		return (List<T>) this.getHibernateTemplate().findByNamedQuery(queryName, args);		//queryname需要在hbm.xml中定义query属性才可以.
	}
	
	/**
	 * 执行增删改操作的命名语句
	 */
	@Override
	public void executeNamedQuery(String queryName, Object... args) {
		SessionFactory sessionFactory = this.getSessionFactory();
		Session session = sessionFactory.getCurrentSession();
		Query query = session.getNamedQuery(queryName);
		if (args !=null && args.length>0) {
			int i=0;
			for (Object obj : args) {
				query.setParameter(i, obj);
			}
		}
		query.executeUpdate();
		
	}
	@Override
	public PageBean pageQuery(PageBean pageBean) {
		int currentPage = pageBean.getCurrentPage();//当前页码
		int pageSize = pageBean.getPageSize();//每页显示记录数
		int total = 0;
		DetachedCriteria detachedCriteria = pageBean.getDetachedCriteria();//离线条件查询对象
		// 查询总记录数,指定hibernate框架发出select count(id) from xxx where ...统计数据量的sql
		detachedCriteria.setProjection(Projections.rowCount());
		List<Long> list = (List<Long>) this.getHibernateTemplate().findByCriteria(detachedCriteria);
		// 从list中得到记录数
		if(list != null && list.size()!=0) {
			Object obj = list.get(0);
			//变成int类型
			Long lobj = (Long) obj;
			total = lobj.intValue();
		}
		//查询当前页展示的数据集合,指定hibernate框架发出select * from xxx where....
		detachedCriteria.setProjection(null);
		//指定hibernate框架将从数据表中查询的每行数据对应的包装成一个实体对象
		detachedCriteria.setResultTransformer(DetachedCriteria.ROOT_ENTITY);
		int firstResult = (currentPage - 1) * pageSize;
		int maxResults = pageSize;
		List recordList = this.getHibernateTemplate().findByCriteria(detachedCriteria, firstResult, maxResults);
		pageBean.setTotal(total);
		pageBean.setRows(recordList);
		return pageBean;
	}
	
}
